﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System
{
    /// <summary>
    /// 字节数据的扩展
    /// </summary>
    public static class ByteEx
    {
        /// <summary>
        /// byte 转换为十六进制字符串
        /// </summary>
        /// <param name="inBytes"></param>
        /// <returns></returns>
        public static string ToHex(this byte[] inBytes)
        {
            var stringOut = new StringBuilder("");
            foreach (var inByte in inBytes)
                stringOut.AppendFormat("{0:X2}", inByte);
            return stringOut.ToString();
        }

        /// <summary>
        /// 转换成16进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToHex(this IList<byte> bytes)
        {
            var stringOut = new StringBuilder("");
            foreach (var inByte in bytes)
                stringOut.AppendFormat("{0:X2} ", inByte);
            return stringOut.ToString();
        }

        /// <summary>
        /// byte 转换为十六进制字符串
        /// </summary>
        /// <param name="inBytes"></param>
        /// <param name="length"> </param>
        /// <returns></returns>
        public static string ToHex(this byte[] inBytes, int length)
        {
            var stringOut = new StringBuilder();
            for (var i = 0; i < length; i++)
            {
                stringOut.AppendFormat("{0:X2} ", inBytes[i]);
            }
            return stringOut.ToString();
        }

        #region wuwei 20151228
        /// <summary>
        /// byte 转换为十六进制字符串
        /// </summary>
        /// <param name="inBytes">输入字节数组</param>
        /// <param name="index">起始坐标</param>
        /// <param name="length">长度</param>
        /// <returns></returns>
        public static string ToHex(this byte[] inBytes,int index, int length)
        {
            var stringOut = new StringBuilder();
            for (var i = index; i < length; i++)
            {
                stringOut.AppendFormat("{0:X2} ", inBytes[i]);
            }
            return stringOut.ToString();
        }
        #endregion

        /// <summary>
        /// 终端协议数据检测,效率大概为执行100万次 78B的包检查 需要3.0秒的时间
        /// </summary>
        /// <param name="message">单个数据包</param>
        /// <returns></returns>
        public static bool Check(this byte[] message)
        {
            //最小长度校验
            if (message.Length <= 8)
                return false;
            //无开始位检验
            if (message[0] != 0x68)
                return false;

            //无开始位校验
            if (message[5] != 0x68)
                return false;

            //无结束位检查
            if (message[message.Length - 1] != 0x16)
                return false;

            //长度计算
            var dataLenght = BitConverter.ToUInt16(message, 1);
            if (message.Length != (dataLenght + 8))
                return false;


            //校验和
            var resultint = 0;
            for (var k = 6; k < message.Length - 2; k++)
            {
                resultint += message[k];
            }
            var result = (byte)(resultint % 256);
            return result == message[message.Length - 2];
        }

     


     

        /// <summary>
        /// 同步消息转义还原
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static byte[] Decape(this byte[] message)
        {
            List<byte> escMessage = null;
            if (message != null)
            {
                escMessage = new List<byte>(message.Length);
                for (int i = 0; i < message.Length; i++)
                {
                    if (message[i] == 0x7d)
                    {
                        if ((i + 1) < message.Length)
                        {
                            if (message[i + 1] == 0x01)
                            {
                                escMessage.Add(message[i]);
                                i++;
                            }
                            else if (message[i + 1] == 0x02)
                            {
                                escMessage.Add(0x7e);
                                i++;
                            }
                        }
                        else
                        {
                            return null;
                        }
                    }
                    else
                    {
                        escMessage.Add(message[i]);
                    }
                }
            }
            return escMessage == null ? null : escMessage.ToArray();
        }


        /// <summary>
        /// 同步消息转义还原
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static byte[] Decape(this List<byte> message)
        {
            List<byte> escMessage = null;
            if (message != null)
            {
                escMessage = new List<byte>();
                for (var i = 0; i < message.Count; i++)
                {
                    if (message[i] == 0x7d)
                    {
                        if ((i + 1) < message.Count)
                        {
                            if (message[i + 1] == 0x01)
                            {
                                escMessage.Add(message[i]);
                                i++;
                            }
                            else if (message[i + 1] == 0x02)
                            {
                                escMessage.Add(0x7e);
                                i++;
                            }
                        }
                        else
                        {
                            return null;
                        }
                    }
                    else
                    {
                        escMessage.Add(message[i]);
                    }
                }
            }
            return escMessage == null ? null : escMessage.ToArray();
        }

        /// <summary>
        /// 同步消息转义
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static byte[] Escape(this byte[] message)
        {
            if (message == null) return null;
            var lst = new List<byte>(message.Length + 100) { message[0] };
            for (var i = 1; i < message.Length - 1; i++)
            {
                switch (message[i])
                {
                    case 0x7d:
                        lst.Add(0x7d);
                        lst.Add(0x01);
                        break;
                    case 0x7e:
                        lst.Add(0x7d);
                        lst.Add(0x02);
                        break;
                    default:
                        lst.Add(message[i]);
                        break;
                }
            }
            lst.Add(message[message.Length - 1]);
            return lst.ToArray();
        }


        /// <summary>
        /// 转义
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static byte[] Escape(this List<byte> message)
        {
            if (message == null) return null;
            var lst = new List<byte>(message.Count + 100) { message[0] };
            for (var i = 1; i < message.Count - 1; i++)
            {
                switch (message[i])
                {
                    case 0x7d:
                        lst.Add(0x7d);
                        lst.Add(0x01);
                        break;
                    case 0x7e:
                        lst.Add(0x7d);
                        lst.Add(0x02);
                        break;
                    default:
                        lst.Add(message[i]);
                        break;
                }
            }
            lst.Add(message[message.Count - 1]);
            return lst.ToArray();
        }


        /// <summary>
        /// 转换成十六进制
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static string ToHex(this List<byte> message)
        {
            if (message == null) return string.Empty;
            var str = new StringBuilder();
            foreach (var t in message)
            {
                str.Append(string.Format("{0:X2} ", t));
            }
            return str.ToString();
        }



        /// <summary>
        /// 转换成十六进制
        /// </summary>
        /// <param name="message"></param>
        /// <param name="index"> </param>
        /// <param name="length"> </param>
        /// <returns></returns>
        public static string ToHex(this List<byte> message, int index, int length)
        {
            if (message == null) return string.Empty;
            var str = new StringBuilder();
            for (var i = index; i < index + length; i++)
            {
                str.Append(string.Format("{0:X2} ", message[i]));
            }
            return str.ToString();
        }

 
    }
}
